package com.atguigu.dga.assess.assessor.cacl;

import com.atguigu.dga.assess.assessor.AssessorTemplate;
import com.atguigu.dga.assess.bean.AssessParam;
import com.atguigu.dga.assess.bean.GovernanceAssessDetail;
import com.atguigu.dga.assess.bean.TDsTaskInstance;
import com.atguigu.dga.assess.service.TDsTaskInstanceService;
import com.atguigu.dga.config.MetaConstant;
import com.atguigu.dga.util.CacheUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by Smexy on 2023/10/31
 *

 检查某张表在DS 当天调度中是否有报错。有则给0分，否则给10分。
    数仓中，除了ODS层的表和 dim_date，其他的表都是以表作为粒度，一天一调度。
        ods层的表和 dim_date都是使用load的方式导入。
        其他的表使用insert方式导入。

 1.遇到Ods层的表和dim_date，忽略
 2.如何判断某一天调度信息和表的对应关系。
        强制要求必须以 库名.表名作为 Task的命名。
        通过 Task实例的name找到对应表的调度情况
 3.如何判断出错了？
        通过状态进行判断，如果状态码是7是成功，6是失败。
 4.一张表在一天的调度中，会失败多少次？
        多次。因为在调度时，会设置重试机制。
    成功多少次？ 1次
 5. DS调度的日期和考评日期是同一天。

 */
@Component("TASK_FAILED")
public class CheckTaskFailed extends AssessorTemplate
{
    @Autowired
    private TDsTaskInstanceService taskInstanceService;
    @Override
    protected void assess(AssessParam param, GovernanceAssessDetail detail) throws ParseException {
        //获取层级和表名
        String dwLevel = param.getMetaInfo().getTableMetaInfoExtra().getDwLevel();
        String name = CacheUtil.getKey(param.getMetaInfo());
        //过滤掉 ods层 和 dim_date
        if ("gmall.dim_date".equals(name) || MetaConstant.DW_LEVEL_ODS.equals(dwLevel)){
            return ;
        }
        //查询数据库的t_ds_task_instance，判断当前表在当天是否执行失败了
        QueryWrapper<TDsTaskInstance> queryWrapper = new QueryWrapper<TDsTaskInstance>()
            .eq("name", name)
            .eq("date(start_time)", param.getAssessDate())
            .eq("state", MetaConstant.TASK_STATE_FAILED);

        List<TDsTaskInstance> failedInstances = taskInstanceService.list(queryWrapper);
        String msg = failedInstances.stream()
                                        .map(t -> t.getName() + "在:" + t.getStartTime() + " 执行失败了.")
                                        .collect(Collectors.joining(","));

        //判断
        if (!failedInstances.isEmpty()){
            assessScore(BigDecimal.ZERO,"任务执行有失败",msg,detail,false,null);
        }

    }
}
